! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! 
      subroutine BOTHGN(VALUE,G,X,iter)

      use globais

      implicit none

      double precision :: X(n)
      double precision :: G(n)

!       double precision :: F
      integer:: i

      double precision :: F1,F2,xaux,xmin,zmin
      double precision :: VALUE      
      integer :: j
      integer :: iflag=2

      double precision :: mapCemX
      integer :: iter


!       real*4, dimension(:,:),allocatable:: creal4

      write(*,*)'                           _________BOTHGN()____________'
!       write(*,*)'                           X fcg  '
!       write(*,*)'                         ',X

! Fobj e Grad pela formulação adjunta
      call modelo2d(X)



   
      call pd2d(omegas(kw),iflag)
  



!       if(iter.ne.iterant)then !aproveita p plotar o modelo se for nova iteracao

! 	      xmin = -(Npml-1)*delta
	      xmin = 0.0d0
	      zmin = 0.00d0
	      write(*,*)'iplot:',iplot, 'kw:',kw,'iter:',iter, 'Nx0:',Nx0,'Nz0:',Nz0,'N:',N


! 	      call systempsimage(c,nx,nz,delta,delta,0.d0,-(Npml-1)*delta,'veloX',&
! 		& 'velocidade (m/s)    ','profundidade (m)    ', 'distancia (m)       ',&
! 		& wbox,Lz0/4.d0,Lx0/4.d0, &
! 		& 0.0d0,Lz0,0.0d0,Lx0)!modelo do pd sem PML
! 
! 	      call systempsimage(c,nx,nz,delta,delta,0.d0,-(Npml-1)*delta,'veloX',&
! 		& 'velocidade (m/s)    ','profundidade (m)    ', 'distancia (m)       ',&
! 		& wbox,Lz0/4.d0,Lx0/4.d0, &
! 		& 0.0d0,Lz0+(Npml-1)*delta,-(Npml-1)*delta,Lx0+(Npml-1)*delta)!modelo do pd com PML


	      call systempsimage(c0,nx0,nz0,deltaX0,deltaZ0,deltaZ0/2.0d0,deltaX0/2.0d0,'veloX',&
		& 'velocidade (m/s)    ','profundidade (m)    ', 'distancia (m)       ',&
		& wbox,Lz0/4.d0,Lx0/4.d0,&
		& 0.0d0,Lz0+(Npml-1)*delta,-(Npml-1)*delta,Lx0+(Npml-1)*delta)!modelo do pi, sem a pml


	      ! Salva a aproximacao em cada iteracao para plotagem da evolucao da aproximacao ao longo do processo
! 	      do j=1,Nz
! 		do i=1,Nx
! 		  creal4(i,j) = SNGL(C(i,j)) !retorna single precision malha do PD
! 		enddo
! 	      enddo
! 	      write(unitsol,rec=iplot+1)((creal4(i,j),j=1,Nz),i=1,Nx)!rec=iplot+1 pq iplot começa em zero

	      do j=1,Nz0
		do i=1,Nx0
		  creal4(i,j) = SNGL(C0(i,j)) !retorna single precision malha do PI
		enddo
	      enddo
	      write(unitsol,rec=iplot+1)((creal4(i,j),j=1,Nz0),i=1,Nx0)!rec=iplot+1 pq iplot começa em zero

	      iplot = iplot +1
	      !fim da plotagem da solucao nesta iteracao
!       endif


      if(kreg.eq.0)then
	  lambdan = 0.0d0
	  Treg = 0.0d0  
      else if(kreg.eq.1)then
	  call regularizaTikho(X,iflag) ! calcula Treg !lambdan  foi lido no arquivo de entrada
! 	      if(Treg.gt.0.0d0 .and. iterant.eq.-1)then!calcula betatikho no chute de cada frequencia
	      if(Treg.gt.0.0d0 .and. betatikho.le.0.0d0)then!so calcula betatikho no chute
		  betatikho=Fobj/Treg !do primeiro chute
		  lambdan = lambdanaux*betatikho ! relativizar o Treg ---> ou seja nessa reg, Treg = betatikho * Treg	      
	      endif

      else if(kreg.eq.2)then

	  if(iter.gt.iterant)then! no inicio desta iteracao, atualiza valores de F(Xn) e lamda_n 
	      FXn = Fobj
	      Xn = X
	      call regularizaL2(X,iflag)! calcula Treg 
	      lambdan = Fobj/Treg  
	  else
	      call regularizaL2(X,iflag)! calcula Treg 
	  endif

      else if(kreg.eq.3)then

	  if(iter.gt.iterant)then! no inicio desta iteracao, atualiza valores de F(Xn) e lamda_n 
	      FXn = Fobj
	      Xn = X
	      call regularizaWL2(X,iflag)! calcula Treg 
	      lambdan = Fobj/Treg  
	  else
	      call regularizaWL2(X,iflag)! calcula Treg 
	  endif

      endif

      if(iterant.eq.-1)then ! só no inicio das novas frequencias,salta linha
	  write(unitF,100)
   	  write(unitFgrad,100)
      endif

      write(unitF,100)kw,iter,Fobj,lambdan,Treg

      if(iter.ne.iterant)then ! só no inicio das novas iteracoes      
	  write(unitFgrad,100)kw,iter,Fobj,lambdan,Treg
      endif
      
      VALUE = Fobj + lambdan * Treg


      do i=1,N
	  G(i) = GradFobj(i) + lambdan * gradTreg(i)
      enddo




      iterant = iter

!fim da  Fobj e Grad pela formulação adjunta


! ! ! ! Fobj e grad por diferencas finitas
! ! !       F = VALUE(X) !aproveito só a fobj
! ! !       ! ao final desta iteracao, atualiza valores de F(Xn) e lamda_n
! ! !       FXn = Fobj
! ! !       Xn = X
! ! ! 
! ! !       F = VALUE(X)!aproveito só o Treg
! ! !       lambdan = Fobj/Treg
! ! ! 
! ! !       F = VALUE(X)! agora sim o custo atualizado
! ! ! 
! ! ! 
! ! !       do j=1,N
! ! ! 	  xaux = X(j)
! ! ! 
! ! ! 	  X(j) = xaux + 0.01d0
! ! ! 	  F1 = VALUE(X)
! ! ! 
! ! ! 	  X(j) = xaux - 0.01d0
! ! ! 	  F2 =  VALUE(X)
! ! ! 
! ! ! 	  G(j) = (F1-F2)/0.02d0
! ! ! 	  X(j) = xaux
! ! !       enddo
! ! ! ! fim Fobj e grad por diferencas finitas










!       F = 0.0
!       do i=1,n
! 	  F=F+(X(i)-i*10)**2
!       enddo
!       F=F*0.5
! 
!       do i=1,n
! 	G(i) = (X(i)-i*10)
!       enddo


      write(*,*)'                           Fobj',VALUE   
      write(*,*)'                           grad:'   
!       write(*,*)'                         ',G     	
      write(*,*)'                           ___________________________'



      return
 100  format(2i10,3E15.6)

      end subroutine BOTHGN